(function () {
  // адрес бывает двух видов: /lesson/update/id/123/part/main  и  /lesson/update?id=123&part=mission
  if (!/lesson\/update/.test(location.pathname)) return;
  var m = location.pathname.match(/\/id\/(\d+)/) || location.search.match(/[?&]id=(\d+)/);
  if (!m) return;
  var ENDPOINT = 'https://script.google.com/macros/s/AKfycbz5y-hkdxNghUkuQxI_hnhUcUlaDLdNGUPPvWcViyy_hOQi3oNZCARD32mUbIEj0vwn/exec';
  var LID = m[1];
  var CACHE_KEY = 'gcfb_last_' + LID;
  function clean(s) { return String(s || '').replace(/\s+/g, ' ').trim(); }
 
  function crumbs() {
    var out = [];
    [].forEach.call(document.querySelectorAll('.breadcrumbs a,.breadcrumb a,[class*="breadcrumb"] a'), function (a) {
      if (/stream\/view/.test(a.getAttribute('href') || '')) out.push(clean(a.textContent));
    });
    return out;
  }
 
  function buildBox() {
    var box = document.createElement('div');
    box.id = 'gcfb-last-box';
    box.innerHTML =
      '<input type="checkbox" id="gcfb-last-cb"> <label for="gcfb-last-cb" style="cursor:pointer">Последний урок модуля</label>' +
      '<div class="text-muted small" style="padding-left:15px">Для анкеты обратной связи: первый урок следующего модуля откроется после анкеты по этому уроку. Сохраняется сразу, кнопка «Сохранить» не нужна.</div>' +
      '<div id="gcfb-last-msg" class="small" style="padding-left:15px;color:#666;min-height:1em"></div>';
    return box;
  }
 
  function mountInline(box) {
    var sel = document.getElementById('MissionParamsObject_answers_default_sort');
    if (!sel || !sel.parentNode || !sel.parentNode.parentNode) return false;
    box.className = 'row row-parent';
    box.style.cssText = 'margin-top:20px';
    var holder = sel.parentNode;
    holder.parentNode.insertBefore(box, holder.nextSibling);
    return true;
  }
  // убрать карточки/дубли от прежних версий скрипта (у них id="gcfb-last")
  function cleanupOld(box) {
    [].forEach.call(document.querySelectorAll('#gcfb-last'), function (old) {
      var c = old.closest('div[style*="position:fixed"]') || old.closest('.row-parent');
      if (c && c !== box && !box.contains(c)) c.parentNode.removeChild(c);
    });
    var dups = document.querySelectorAll('#gcfb-last-box');
    for (var i = 1; i < dups.length; i++) dups[i].parentNode.removeChild(dups[i]);
  }
 
  function wire(box) {
    var cr = crumbs(), courseTitle = '', moduleTitle = '';
    cr.forEach(function (t) { if (/\s[-–—]\s*старт/i.test(t)) courseTitle = t; });
    if (cr.length && /модул/i.test(cr[cr.length - 1])) moduleTitle = cr[cr.length - 1];
    var h1 = document.querySelector('h1');
    var title = h1 ? clean(h1.textContent) : '';
    var cb = box.querySelector('#gcfb-last-cb'), msg = box.querySelector('#gcfb-last-msg');
 
    // мгновенно показываем последнее известное состояние, сервер уточнит его позже
    var cached = null;
    try { cached = localStorage.getItem(CACHE_KEY); } catch (e) {}
    if (cached !== null) { cb.checked = cached === '1'; msg.textContent = 'Обновляется…'; }
    else { cb.disabled = true; msg.textContent = 'Загрузка…'; }
 
    fetch(ENDPOINT + '?action=lastflag&lesson_id=' + LID + '&_=' + Date.now())
      .then(function (r) { return r.json(); })
      .then(function (r) {
        cb.checked = !!r.last; cb.disabled = false;
        try { localStorage.setItem(CACHE_KEY, r.last ? '1' : '0'); } catch (e) {}
        msg.textContent = r.registered ? (r.last ? 'Отмечен как последний' : 'Не отмечен') : 'Урока ещё нет в таблице';
      }).catch(function () { cb.disabled = false; msg.textContent = 'Нет связи с таблицей'; });
 
    cb.addEventListener('change', function () {
      var want = cb.checked, key = '';
      try { key = localStorage.getItem('gcfb_admin_key') || ''; } catch (e) {}
      if (!key) key = prompt('Ключ администратора (ADMIN_KEY из скрипта Google):') || '';
      if (!key) { cb.checked = !want; return; }
      cb.disabled = true; msg.textContent = 'Сохранение…';
      fetch(ENDPOINT, {
        method: 'POST', headers: { 'Content-Type': 'text/plain;charset=utf-8' },
        body: JSON.stringify({ action: 'setLast', key: key, lesson_id: LID, last: want, title: title, course_title: courseTitle, module_title: moduleTitle })
      }).then(function (r) { return r.json(); }).then(function (r) {
        if (!r.ok) { try { localStorage.removeItem('gcfb_admin_key'); } catch (e) {} throw new Error(r.error || 'error'); }
        try { localStorage.setItem('gcfb_admin_key', key); localStorage.setItem(CACHE_KEY, want ? '1' : '0'); } catch (e) {}
        msg.textContent = (want ? 'Сохранено: последний. ' : 'Отметка снята. ') +
          'Группа: ' + (r.group || '—') + ', ступень: ' + (r.step || '—') + ', модуль: ' + (r.mod || '—');
      }).catch(function (e) {
        cb.checked = !want; msg.textContent = 'Не удалось сохранить: ' + e.message;
      }).then(function () { cb.disabled = false; });
    });
  }
 
  function init() {
    // галочка показывается только там, где есть поле "Сортировка ответов по умолчанию" (вкладка "Задание и комментарии");
    // на остальных вкладках ничего не выводится. Следим за страницей постоянно: если GetCourse подгрузит или перерисует вкладку,
    // галочка появится снова.
    var box = buildBox(), wired = false;
    if (window.console) console.log('[gcfb] галочка "последний урок модуля" активна, урок', LID);
 
    function ensure() {
      cleanupOld(box);                                   // дубли и плавающие карточки от старых версий
      var existing = document.getElementById('gcfb-last-box');
      if (existing && existing !== box) return;          // уже есть другой экземпляр (скрипт вставлен дважды)
      if (!document.getElementById('MissionParamsObject_answers_default_sort')) return;
      if (document.documentElement.contains(box)) return;
      if (mountInline(box) && !wired) { wired = true; wire(box); }
    }
 
    ensure();
    try {
      new MutationObserver(ensure).observe(document.documentElement, { childList: true, subtree: true });
    } catch (e) {}
    setInterval(ensure, 1000);                           // запасной вариант, если наблюдатель не сработает
  }
 
  if (document.body) init();
  else document.addEventListener('DOMContentLoaded', init);
})();